using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Runtime.Session;
using Microsoft.EntityFrameworkCore;
using Mt.Site.Application.Taxonomys.Dto;
using Mt.Site.Application.Taxonomys.FrontDto;
using Mt.Site.Core.Base.Domain.Entities.ShortId;
using Mt.Site.Core.Base.Localization;
using Mt.Site.Core.Base.Utils;
using Mt.Site.Core.Taxonomys;
using Mt.Site.Core.Taxonomys.Entities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Mt.Site.Application.Taxonomys
{
    public class TaxonomyFrontAppService: MtSiteFrontendAppServiceBase, ITaxonomyFrontAppService
    {
        private MyLocalizationHelper _navLocalizeHelper
            = new MyLocalizationHelper(MtSiteConsts.LocalizationSourceName_Navigation);
        private readonly ITaxonomysManager _taxonomysManager;

        private readonly IRepository<TaxonomysItem, Guid> _taxonomysItemRepository;

        private readonly IRepository<TaxonomysItemBind, Guid> _taxonomysItemBindRepository;

        public TaxonomyFrontAppService(
                ITaxonomysManager taxonomysManager,
                IRepository<TaxonomysItem, Guid> taxonomysItemRepositorym,
                IRepository<TaxonomysItemBind, Guid> taxonomysItemBindRepository)
        {
            _taxonomysManager = taxonomysManager;
            _taxonomysItemRepository = taxonomysItemRepositorym;
            _taxonomysItemBindRepository = taxonomysItemBindRepository;
        }

        /// <inheritdoc/>
        public async Task<List<TaxonomyFrontItem>> GetTaxonomyCollectionsAsync(EntityDto<Guid> input)
        {
            var list = await _taxonomysManager.GetTaxonomyItemCollectionAsync(input.Id, AbpSession.CultureName());
            return ObjectMapper.Map<List<TaxonomyFrontItem>>(list);
        }

        /// <inheritdoc/>
        public async Task<List<TaxonomyItemLevel1Dto>> GetTaxonomyItemLevel1(EntityDto<Guid> input)
        {
            var query = from taxonomyItem in _taxonomysItemRepository.GetAll()
                        join itemBind in _taxonomysItemBindRepository.GetAll()
                        on taxonomyItem.Id equals itemBind.ItemId
                        where taxonomyItem.TypeId == input.Id && taxonomyItem.ParentId == null && taxonomyItem.IsActive
                        orderby taxonomyItem.Norder
                        select new TaxonomyItemLevel1Dto
                        {
                            Id = taxonomyItem.Id,
                            DisplayName = taxonomyItem.DisplayName,
                            Value = taxonomyItem.Value,
                            Pic1 = taxonomyItem.Pic1,
                            Pic2 = taxonomyItem.Pic2,
                            LinkUrl = taxonomyItem.LinkUrl,
                            AuxiliaryId = taxonomyItem.AuxiliaryId
                        };
            var list = await query.ToListAsync();
            if (list != null)
            {

                list.ForEach(item =>
                  {
                      var localName = _navLocalizeHelper.GetStringOrNull(item.Id.ToString(), CultureInfo.GetCultureInfo(AbpSession.CultureName()));

                      if (!string.IsNullOrWhiteSpace(localName))
                      {
                          item.DisplayName = localName;
                      }
                  });

                return list;
            }
            else
            {
                return new List<TaxonomyItemLevel1Dto>();
            }
        }

        /// <inheritdoc/>
        public async Task<List<TaxomonyItemNext>> GetTaxonomyLevelNext(EntityDto<Guid> input)
        {
            var query = from taxonomyItem in _taxonomysItemRepository.GetAll()
                                .Where(item => item.ParentId == input.Id && item.IsActive)
                        join itemBind in _taxonomysItemBindRepository.GetAll()
                        on taxonomyItem.Id equals itemBind.ItemId
                        orderby taxonomyItem.Norder
                        select new TaxomonyItemNext
                        {
                            Id = taxonomyItem.Id,
                            DisplayName = taxonomyItem.DisplayName,
                            Value = taxonomyItem.Value,
                            Pic1 = taxonomyItem.Pic1,
                            Pic2 = taxonomyItem.Pic2,
                            LinkUrl = taxonomyItem.LinkUrl,
                            AuxiliaryId = taxonomyItem.AuxiliaryId
                        };
            var list = await query.ToListAsync();

            var result = new List<TaxomonyItemNext>();
            list.ForEach(item =>
            {
                var localName = _navLocalizeHelper.GetStringOrNull(item.Id.ToString(), CultureInfo.GetCultureInfo(AbpSession.CultureName()));

                if (!string.IsNullOrWhiteSpace(localName))
                {
                    item.DisplayName = localName;
                }
            });
            return list;
        }

        public async Task<List<TaxomonyItemNext>> GetTaxonomyItemByIdsAsync(GetTaxonomyItemInput input)
        {
            var levelIds = input.IdListStr.TryGetArryFromStrBySplit<Guid>(",");


            var query = from taxonomyItem in _taxonomysItemRepository.GetAll()
                        where levelIds.Contains(taxonomyItem.Id)
                        select new TaxomonyItemNext
                        {
                            Id = taxonomyItem.Id,
                            DisplayName = taxonomyItem.DisplayName,
                            Value = taxonomyItem.Value,
                            Pic1 = taxonomyItem.Pic1,
                            Pic2 = taxonomyItem.Pic2,
                            LinkUrl = taxonomyItem.LinkUrl,
                            AuxiliaryId = taxonomyItem.AuxiliaryId
                        };
            var list = await query.ToListAsync();

            var result = new List<TaxomonyItemNext>();
            list.ForEach(item =>
            {
                var localName = _navLocalizeHelper.GetStringOrNull(item.Id.ToString(), CultureInfo.GetCultureInfo(AbpSession.CultureName()));

                if (!string.IsNullOrWhiteSpace(localName))
                {
                    item.DisplayName = localName;
                }
            });
            return list;
        }

        public async Task<List<TaxonomyFrontItem>> GetTaxonomyTreeByParentIdAsync(GetTaxonomyTreeByParentIdInput input)
        {
            var list = await _taxonomysManager.GetTaxonomyItemTreeByParentIdAsync(input.ParentId, input.TypeId, AbpSession.CultureName());
            return ObjectMapper.Map<List<TaxonomyFrontItem>>(list);
        }

        public async Task<List<TaxonomyItemDataOut>> GetTaxonomyLevelNextTree(GetTaxonomyLevelNextTreeInput input)
        {
            var parentItem = await _taxonomysItemRepository.FirstOrDefaultAsync(item => item.Id == input.ParentId);
            if(parentItem == null)
            {
                return new List<TaxonomyItemDataOut>();
            }

            var code = $"{parentItem.Code}.";

            var query = from taxonomyItem in _taxonomysItemRepository.GetAll()
                        join itemBind in _taxonomysItemBindRepository.GetAll()
                        on taxonomyItem.Id equals itemBind.ItemId
                        where taxonomyItem.TypeId == input.TypeId && taxonomyItem.Code.StartsWith(code) && taxonomyItem.IsActive
                        orderby taxonomyItem.Code
                        select taxonomyItem;
            var list = await query.ToListAsync();

            return ObjectMapper.Map<List<TaxonomyItemDataOut>>(list);
        }
    }
}
